package com.example.lsrsbackend.service.impl;

import com.example.lsrsbackend.exception.SeatException;
import com.example.lsrsbackend.mapper.ReservationMapper;
import com.example.lsrsbackend.mapper.SeatMapper;
import com.example.lsrsbackend.model.Reservation;
import com.example.lsrsbackend.model.Seat;
import com.example.lsrsbackend.model.view.SeatVO;
import com.example.lsrsbackend.service.SeatService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

@Service
@Slf4j
public class SeatServiceImpl implements SeatService {

    @Autowired
    private SeatMapper seatMapper;

    @Autowired
    private ReservationMapper reservationMapper;

    @Override
    public List<Seat> getAllSeatStatus() {
        List<Seat> seats = seatMapper.selectAll();
        return seats.stream().collect(Collectors.toList());
    }

    @Override
    public List<Seat> getSeatsByArea(String area) {
        Long floorAreaId = Long.parseLong(area);
        List<Seat> seats = seatMapper.selectByFloorAreaId(floorAreaId);
        return seats.stream().collect(Collectors.toList());
    }

    @Override
    public void initSeatData() {

    }

    @Override
    public void syncSeatStatusToRedis() {

    }

//    @Override
//    public void initSeats(List<Seat> seats) {
//        for (Seat seat : seats) {
//            seatMapper.insert(seat);
//        }
//        log.info("初始化 {} 个座位数据", seats.size());
//    }

    @Override
    public SeatVO getSeatDetail(String seatId) {
        Long seatIdLong = Long.parseLong(seatId);
        Seat seat = seatMapper.selectById(seatIdLong);
        if (seat == null) {
            throw new SeatException("座位不存在");
        }
        return convertToVO(seat);
    }

    @Override
    public void updateSeatStatus(String seatId, String status, String currentUser, String reservationId) {
        // 对于纯数据库实现，座位状态是通过查询预约表动态计算的
        // 这个方法可以留空，或者记录日志
        log.debug("座位状态更新请求 - seatId: {}, status: {}, user: {}, reservation: {}",
                seatId, status, currentUser, reservationId);
    }


    //座位新增
    @Override
    public Seat addSeat(Seat seat) {
        // 检查座位号是否重复
        int count = seatMapper.countByFloorAndSeatNumber(seat.getFloorAreaId(), seat.getSeatNumber());
        if (count > 0) {
            throw new SeatException("该楼层下已存在相同座位号");
        }

        int result = seatMapper.insertSeat(seat);
        if (result == 0) {
            throw new SeatException("添加座位失败");
        }

        return seatMapper.selectById(seat.getId());
    }


    //座位更新
    @Override
    public Seat updateSeat(Long id, Seat seat) {
        Seat existingSeat = seatMapper.selectById(id);
        if (existingSeat == null) {
            throw new SeatException("座位不存在");
        }

        // 检查座位号是否重复（排除当前座位）
        int count = seatMapper.countByFloorAndSeatNumberExcludingId(
                seat.getFloorAreaId(), seat.getSeatNumber(), id);
        if (count > 0) {
            throw new SeatException("该楼层下已存在相同座位号");
        }

        seat.setId(id);
        int result = seatMapper.updateSeat(seat);
        if (result == 0) {
            throw new SeatException("更新座位失败");
        }

        return seatMapper.selectById(id);

    }


    //删除座位

    @Override
    public void deleteSeat(Long id) {
        Seat existingSeat = seatMapper.selectById(id);
        if (existingSeat == null) {
            throw new SeatException("座位不存在");
        }

        // 检查是否有相关预约
        // 这里可以添加业务逻辑检查，比如座位是否有进行中的预约

        int result = seatMapper.deleteSeat(id);
        if (result == 0) {
            throw new SeatException("删除座位失败");
        }
    }



    private SeatVO convertToVO(Seat seat) {
        SeatVO vo = new SeatVO();
        vo.setId(seat.getId());
        vo.setSeatNumber(seat.getSeatNumber());
        vo.setFloorAreaId(seat.getFloorAreaId());
        vo.setSeatType(seat.getSeatType());
        vo.setBaseStatus(seat.getBaseStatus());

        // 动态计算实时状态
        String realTimeStatus = calculateRealTimeStatus(seat.getId());
        vo.setStatus(realTimeStatus);
        vo.setAvailable("AVAILABLE".equals(realTimeStatus));

        // 设置前端展示字段
        vo.setStatusText(getStatusText(realTimeStatus));
        vo.setStatusColor(getStatusColor(realTimeStatus));
        vo.setSeatTypeText(getSeatTypeText(seat.getSeatType()));
        vo.setBaseStatusText(getBaseStatusText(seat.getBaseStatus()));

        return vo;
    }

    private String calculateRealTimeStatus(Long seatId) {

        // 首先获取座位的基础状态
        Seat seat = seatMapper.selectById(seatId);
        if (seat == null) {
            return "AVAILABLE";
        }

        // 如果基础状态是暂离，直接返回暂离
        if (seat.getBaseStatus() == Seat.BaseStatus.AWAY) {
            return "AWAY";
        }
        // 查询座位当前的有效预约
        List<Reservation> activeReservations = reservationMapper.selectActiveReservationsBySeatAndDate(seatId, new Date());

        if (activeReservations.isEmpty()) {
            return "AVAILABLE";
        }

        Reservation reservation = activeReservations.get(0);
        if (reservation.getStatus() == Reservation.Status.pending_fulfillment) {
            return "RESERVED";
        } else if (reservation.getStatus() == Reservation.Status.fulfilled) {
            return "OCCUPIED";
        }

        return "AVAILABLE";
    }

    private String getStatusText(String status) {
        switch (status) {
            case "AVAILABLE": return "可用";
            case "RESERVED": return "已预约";
            case "OCCUPIED": return "已占用";
            case "AWAY": return "暂离中";
            default: return "未知";
        }
    }

    private String getStatusColor(String status) {
        switch (status) {
            case "AVAILABLE": return "green";
            case "RESERVED": return "orange";
            case "OCCUPIED": return "red";
            case "AWAY": return "blue";
            default: return "gray";
        }
    }

    private String getSeatTypeText(Seat.SeatType seatType) {
        switch (seatType) {
            case normal: return "普通座位";
            case computer: return "电脑座位";
            case discussion: return "讨论区";
            case standing: return "站立座位";
            default: return "未知类型";
        }
    }

    private String getBaseStatusText(Seat.BaseStatus baseStatus) {
        switch (baseStatus) {
            case  AVAILABLE: return "可预约";
            case RESERVED: return "已被预约";
            case OCCUPIED: return "正在使用";
            case AWAY: return "暂离中";
            default: return "未知状态";
        }
    }
}